package it.storm.solution;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 832. 翻转图像
 * https://leetcode-cn.com/problems/flipping-an-image/
 */
public class Solutions_832 {
    public static void main(String[] args) {
        int[][] matrix1 = {{1, 1, 0},
                           {1, 0, 1},
                           {0, 0, 0}};
        // output: {{1, 0, 0}, {0, 1, 0}, {1, 1, 1}}
//        解释: 首先翻转每一行: {{0, 1, 1}, {1, 0, 1}, {0, 0, 0}}；
//        然后反转图片: {{1, 0, 0}, {0, 1, 0}, {1, 1, 1}}

        int[][] matrix2 = {{1, 1, 0, 0},
                           {1, 0, 0, 1},
                           {0, 1, 1, 1},
                           {1, 0, 1, 0}};
        // output: {{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 1}, {1, 0, 1, 0}}
//        解释: 首先翻转每一行: {{0, 0, 1, 1}, {1, 0, 0, 1}, {1, 1, 1, 0}, {0, 1, 0, 1}}；
//        然后反转图片: {{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 1}, {1, 0, 1, 0}}

        List<int[][]> inputs = new ArrayList<>();
        inputs.add(matrix1);
        inputs.add(matrix2);

        for (int[][] input : inputs) {
            int[][] result = flipAndInvertImage(input);
            System.out.println(Arrays.deepToString(result));
        }
    }

    /**
     * 优化思路：水平翻转时，若两个元素不同，那么是不需要做操作的，因为逆序后再翻转，还是原来的数
     * 只有交换的两个元素相同时，就需要翻转一下
     */
    public static int[][] flipAndInvertImage(int[][] A) {
        if (A == null) {
            return A;
        }
        for (int[] arr : A) {
            int left = 0, right = arr.length - 1;
            while (left <= right) {
                if (arr[left] == arr[right]) {
                    // 翻转
                    if (arr[left] == 1) {
                        arr[left] = 0;
                        arr[right] = 0;
                    } else {
                        arr[left] = 1;
                        arr[right] = 1;
                    }
                }
                left ++;
                right --;
            }
        }
        return A;
    }

    /**
     * 模拟实现
     * 先逆序，后转化
     */
    public static int[][] flipAndInvertImage2(int[][] A) {
        if (A == null) {
            return A;
        }
        for (int[] arr : A) {
            int left = 0, right = arr.length - 1;
            while (left <= right) {
                // 水平翻转
                int temp = arr[right];
                arr[right] = arr[left];
                arr[left] = temp;

                if (left == right) {
                    // 翻转
                    if (arr[left] == 0) {
                        arr[left] = 1;
                    } else {
                        arr[left] = 0;
                    }
                    break;
                }

                // 翻转图片
                if (arr[left] == 0) {
                    arr[left] = 1;
                } else {
                    arr[left] = 0;
                }
                if (arr[right] == 0) {
                    arr[right] = 1;
                } else {
                    arr[right] = 0;
                }
                left ++;
                right --;
            }
        }
        return A;
    }
}
